<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/5/17 0017
 * Time: 上午 10:42
 */

namespace App\WebSocket;

use App\Model\ParamsBean;
use App\Utility\BaseEnum;
use App\Common\BaseComm;
use App\Common\AuthCommon;
use Swoole\Timer;
use EasySwoole\Socket\AbstractInterface\Controller;
use EasySwoole\EasySwoole\Config;
use EasySwoole\Component\Pool\PoolManager;
use App\Utility\Pool\RedisPool;
use EasySwoole\EasySwoole\ServerManager;
use App\Common\GameCommon;
use App\GameService\games\PlayHelp;
use App\Common\PlayCommon;
use App\Enum\SysEnum;



class WsBase extends Controller
{
    protected $redisObj = null;
    protected $baseRoutes = null;
    protected $paramsBean = null;
    protected $current_treaty = null; //当前协议码；用于存储当前协议值
    protected $current_client_id = null;
    protected $loginUserInfo = null;    //登录玩家信息
    protected $loginUserId = null;      //登录玩家ID
    
    /**
     * TODO 没有找到控制器中的方法
     * @param null|string $actionName
     */
    function actionNotFound(?string $actionName) {
        $this->ResError(-1,"Method {$actionName} actionNotFound (未定义)"); 
    }
    
    /**
     * TODO 请求返回结果
     * @param null|string $actionName
     */
    function ResError($code = -1,$oldErrorMsg ='未知错误',$level = 0)
    {
        $Errs = BaseEnum::RESPONSE_MESSAGES;
        $tempXYs = BaseEnum::RESPOSE_MSG_OUTS;  //强行退出协议
        $level = (!empty($tempXYs) && in_array($code, $tempXYs)) ? SysEnum::RETURN_MSG_LEVEL_3 : $level;     //强行退出类型
        $paramsBean = new ParamsBean();
        $ErrorMsg = isset($Errs[$code]) ? $Errs[$code] : $oldErrorMsg;
        $paramsBean -> setStatus(0);                        //普通方法
        $paramsBean->setUniosix(BaseEnum::XYM_0X02);        //设置当前16进制协议码
        $paramsBean->setCode(intval($code));
        $paramsBean->setMsg($ErrorMsg);                     //设置错误码；code,错误等级：level, 返回数据为NULL;
        if (isset($level) && intval($level) > 0) {  $paramsBean -> setStatus($level); }       //强制退出错误
        $responseJson = $paramsBean->responseJson();
        BaseEnum::Logger("错误反馈WEB端：Res Error Data code=({$code}) : ".$ErrorMsg."({$oldErrorMsg})" , 'user-login');
        AuthCommon::pushFrontWeb($this->current_client_id,$responseJson);
    }
    
    /**
     * TODO 请求返回结果
     * @param null|string $actionName
     */
    function ResOK($data = [],$ErrorMsg ='成功')
    {
        //执行异常错误
        $paramsBean = new ParamsBean();
        $paramsBean->setCode(200);
        $paramsBean->setUniosix($this->current_treaty);     //设置当前16进制协议码
        $paramsBean->setData($data);                        //设置返回值为什么数据
        $responseJson = $paramsBean->responseJson();
        $loginFd = $this->current_client_id;
        BaseEnum::Logger("请求成功WEB端：FD=({$loginFd}) : MSG： ".$responseJson , 'user-login');
        AuthCommon::pushFrontWeb($loginFd,$responseJson);
    }
    
    /**
     * TODO 成功和失败；
     */
    function ResSUCCESS($status = 0, $msg = "失败") {
        //执行异常错误
        $result = ['m' => BaseEnum::XYM_0X02,"data"=>"","code"=> $status,"level"=> 1,"msg"=> $msg];
        $responseJson = json_encode($result);
        AuthCommon::pushFrontWeb($this->current_client_id,$responseJson);
    }
    
    
    

    /**
     * TODO 获取登录信息
     * @param number $loginUid
     * @return array
     */
    public function LoginPlayUser(& $loginUid = 0) {
        $loginUid = $this->loginUserId;
        return $this->loginUserInfo;
    }
   
    /**
     * TODO 拉取游戏状态
     */
    public function pullGameStatus($gameId,$userInfo = FALSE ,$ifRoom = FALSE){
        $agentId = $userInfo['recUid'] ?? 0 ; 
        $isNation = $userInfo['isNation'] ?? 0;
        if($ifRoom === TRUE && $gameId > 1000){
            $gameId = intval(floor($gameId/10)); 
        }
        if(!$gameId) return FALSE;
        //TODO 全民代理暂不判断
        if (isset($isNation) && intval($isNation) === 1) {
            return TRUE;
        }
        
        //TODO 普通代理：获取当前代理已开能的游戏列表
        return BaseComm::DbQuery(function($db) use ($gameId , $agentId){
            $result = $db->where("agentId",$agentId)->where("gameId",$gameId)-> getOne('qc_agent_games',['gameId','agentId','gameStatus']);
            BaseEnum::Logger("pullGameStatus获取游戏数据: " . json_encode($result) ,"user-login");
            if (isset($result['gameStatus']) && intval($result['gameStatus']) === 1) {
                return TRUE;
            }return FALSE;
        });
    }
    
    /**
     * TODO 进入控制器的时候做一些验证数据的工作
     * @param null|string $actionName
     * @return bool
     */
    function onRequest(?string $actionName): bool
    {
        //TODO 组装HTTP的参数内容；
        $controller = $action = '';
        $gamePlayObj = null ;
        $requestArgs = $this->caller()->getArgs();
        $clientFd =  $this->caller()->getClient() -> getFd();
        try{
            $clientInfo = ServerManager::getInstance()->getSwooleServer()->getClientInfo($clientFd);
            BaseEnum::Logger("WsBaseClient-INFO: ". json_encode($requestArgs)."=>" . json_encode($clientInfo) ,"user-login");
            $clientIP = $clientInfo['remote_ip'] ?? "" ;    // 客户端信息:====> 获取用户IP地址
            $userClient = array("clientIp" => $clientIP, "wsStatus"=> $clientInfo['websocket_status'] ?? 0,"prot"=> $clientInfo['server_port'] ?? '');
            BaseEnum::Logger("消息客户端信息: " . json_encode($userClient,true) ,"user-login");
            $hanldExVal = isset($requestArgs['m']) ? intval($requestArgs['m']) : 0 ;            //获取参数（指定到路由内容）
            $paraData = isset($requestArgs['d']) ? $requestArgs['d'] : FALSE ;                  //请求数据
            $getUrls = isset($requestArgs['localUrls']) ? $requestArgs['localUrls'] : FALSE ;   //路由（登录验证）
            $purls = !empty($getUrls) ? json_encode($getUrls) : '' ;    //解析路由数据:传过来的数据就不解析
            $dataJson = (!empty($paraData) && (is_object($paraData) || is_array($paraData))) ? json_encode($paraData) : '{}' ;  //字符串
            $dataArray = !empty($dataJson) ? json_decode($dataJson,true): [];
            $GameID = isset($dataArray["gameId"]) ? intval($dataArray["gameId"]) :0 ;                                           //游戏ID的值；
            $ROOMID = isset($dataArray["gameRoomId"]) ? intval($dataArray["gameRoomId"]) :0 ;                                   //游戏ID的值；
            BaseEnum::Logger('连接初始化：onRequest->客户FD,协议码=---'.json_encode([$clientFd,$hanldExVal,$purls]) ,'user-login');
            //根据提交的参数内容来判断（如果有gameId,和gameRoomId字段就加实例化类）
            if ($GameID <= 0 &&  isset($ROOMID) && $ROOMID > 1000) { $GameID = intval(substr("{$ROOMID}", 0,3));   }            //取游戏ID
            if(isset($GameID) && intval($GameID) > 0){ 
                $gamePlayObj = BaseEnum::getClassObject(FALSE,$GameID);     //实列化当前游戏类 ；
                BaseEnum::Logger("预先实例化Object：[Game ID={$GameID}]--->" . @$gamePlayObj->baseGameName, 'user-login');
            }
            $paramsBean = new ParamsBean();             //组合参数值；
            $paramsBean->setFd($clientFd);              //客户端ID
            $paramsBean->setUniosix($hanldExVal);       //当前协议值
            $paramsBean->setRouteClientIP($clientIP);   //设置IP地址
            if ($hanldExVal == -1) {                    //请求数据为心跳数据；
                $paramsBean->setData('');
                AuthCommon::pushFrontWeb($clientFd,0x1);    //PING值显示值0x1
                return FALSE;
            }else{
                $this->current_client_id = $clientFd;
                $redis = PoolManager::getInstance()->getPool(RedisPool::class)->getObj(Config::getInstance()->getConf('REDIS.POOL_TIME_OUT'));  //连接池
                if ($redis) {
                    $this->redisObj = $redis;
                } else {
                    throw new \Exception('Redis Fail  :'.$this->request()->getUri()->getPath().' error,Redis Pool is Empty');                   //直接抛给异常处理，不往下
                }
                
                if(isset($getUrls) && !empty($getUrls) && sizeof($getUrls) === 2){
                    $controller = isset($getUrls[0]) ? $getUrls[0] : '';
                    $action = isset($getUrls[1]) ? $getUrls[1] : 'index';
                }else {
                    //解析数据
                    $reqBms = BaseEnum::REQUEST_GROUTES ;
                    $hanldExp = (isset($hanldExVal) && $hanldExVal !== FALSE) ? hexdec($hanldExVal) : 0;        //16进制转成10进制操作；
                    $paraUrl  = isset($reqBms[$hanldExp]) ? $reqBms[$hanldExp] :  "";
                    $paraUrls = !empty($paraUrl) ? explode('-', $paraUrl): false ;                              //URL地址
                    $controller = isset($paraUrls[0]) ? trim($paraUrls[0]):"" ;                                 //控制器
                    $action = (!empty($paraUrls) && isset($paraUrls[1])) ? trim($paraUrls[1]) : "index" ;       //方法名
                }
                
                //解析路由映射值；
                BaseEnum::Logger('连接协议码：'. $hanldExVal .'  request Data : '.json_encode([$dataJson,$purls]),'user-login');
                $paramsBean->setController($controller);
                $paramsBean->setAction($action);
                $paramsBean->setData($dataJson);
                if (isset($gamePlayObj) && !empty($gamePlayObj)) {
                    $paramsBean->setGameObject($gamePlayObj);   //把游戏类放在整个Bean中；
                }
                
                //组装关系映射写入redis
                BaseEnum::Logger('序列化： Beam-Data : '.json_encode($getUrls),'user-login');
                if (!$clientFd || !$dataJson || !$controller) {
                    $this->ResError(-1,"请求参数异常");
                    return FALSE;
                }
            }
            
            //OnOpen::wssAutoLoad($paramsBean); ===== 初始化数据;并缓存最新的数据内容到缓存Redis中
            $this->paramsBean = $paramsBean;
            $this->current_treaty = $hanldExVal; 
            $notPloginList = BaseEnum::getNoLoginXYM();
            if (!empty($notPloginList) && in_array($hanldExVal, $notPloginList)) {
                return TRUE;    //TODO 不用验证
            }
            
            //TODO 验证需要登录权限
            $this->loginUserInfo = AuthCommon::getLoginUser($clientFd);
            $this->loginUserId = isset($this->loginUserInfo["uid"]) ? intval($this->loginUserInfo["uid"]) :0 ; 
            if (!$this->loginUserInfo || empty($this->loginUserInfo) || $this->loginUserId <= 0) {
                $this->ResError(BaseEnum::MSG_0XF7,"玩家未登录，或玩家已掉线请重试", 1);   //重新登录
                return FALSE;   //TODO 验证失败
            }
        }catch (\Throwable $e){
            BaseEnum::Logger("请求异常: ".$e->getMessage(),'user-login');
            return FALSE;
        }
        return TRUE;
    }

    /**
     * GC垃圾回收处理
     */
    public function gc() {
        BaseEnum::Logger("WsBase___redis-GC 回收 FD={$this->current_client_id} Free Redis","user-login");
        PoolManager::getInstance()->getPool(RedisPool::class) -> recycleObj($this->redisObj);             //GC垃圾回收
        parent::gc();
    }
    
    /**
     * TODO 等待游戏开始逻辑处理
     * @param int $gameRId 房间ID
     * @param int $loginFd 登录FD 
     * @param boolean $userId 用户ID值
     */
    protected function waitStartTimeOut($gameRId,$loginFd,$userId=FALSE) {
        // 成功加入游戏列队；进入等待(等待匹配其它玩家)
        $game_wait_interval = Config::getInstance()->getConf('COMMON.player_wait_interval'); // 游戏匹配等待时间长
        BaseEnum::Logger("游戏匹配等待处理中：WsBase-(waitGameStart)-[房间ID：{$gameRId}],---(匹配等待{$game_wait_interval}秒) 稍后检测[玩家UID={$userId}|fd=$loginFd]是否还在匹配列队中...", 'user-login');
        //TODO 异步等待 暂停5秒后还在等待中，就踢出排列 ；
        Timer::after($game_wait_interval * 1000, function () use ($gameRId, $loginFd, $userId) {
            $joinList = BaseComm::distMemoryPlayer($gameRId,FALSE);
            if (! empty($joinList) && array_key_exists($userId, $joinList)) {   // 玩家失败要退出列队等待中
                unset($joinList[$userId]);
                BaseComm::distMemoryPlayer($gameRId, TRUE,$joinList);           // 保存数据；
                BaseEnum::Logger("等待匹配中：-(WsBase)-Waiting == [房间ID：{$gameRId}],---([fd={$loginFd}]等待超时，踢出[UID={$userId}]列队)------>>>>>" . json_encode($joinList), 'user-login');
                $pushArr = ['m' => BaseEnum::XYM_0X16, "data" => null, "code" => BaseEnum::MSG_0XF9, "msg" => "匹配游戏失败，玩家数目不够"];
                AuthCommon::pushFrontWeb($loginFd, json_encode($pushArr));      // 推送
            }
        });
    }
    
    
    /**
     * TODO 获取机器人 玩家列表
     * @param int $robNum 匹配机器人数目；
     * @return array  玩家列表
     */
    protected function getFreeRobotUsers($gameId,$roomInfo = FALSE,$robNum = 1){
        $groupPlayers = [];
       /*  $freePlayer = [
            10020=> ["uid"=> 10020,"name"=> "robot0005","agentId"=> 10010,"gender"=> 0,"head_url"=> 2,"loginFd"=> 200],
            10017=> ["uid"=> 10017,"name"=> "robot0002","agentId"=> 10010,"gender"=> 0,"head_url"=> 3,"loginFd"=> 201],
            10018=> ["uid"=> 10018,"name"=> "robot0003","agentId"=> 10010,"gender"=> 1,"head_url"=> 4,"loginFd"=> 202],
            10019=> ["uid"=> 10019,"name"=> "robot0004","agentId"=> 10010,"gender"=> 0,"head_url"=> 5,"loginFd"=> 203],
            10021=> ["uid"=> 10016,"name"=> "robot0001","agentId"=> 10010,"gender"=> 0,"head_url"=> 6,"loginFd"=> 204]
        ]; */
        $freePlayer = PlayCommon::getFreeRobotsUser($gameId,$robNum); 
        BaseEnum::Logger("匹配空闲机器人：{$gameId} (匹配数量：{$robNum}, 返回=>" . json_encode($freePlayer) , 'user-login');
        if(!$freePlayer){
            return FALSE;
        }
        $smallMoney = 1000 ; //房间最低额
        foreach ($freePlayer as $userid => $oneplayer){
            if($userid > 0 && !empty($oneplayer) && isset($oneplayer['loginFd']) && intval($oneplayer['loginFd']) >0){
               $robotMoney = AuthCommon::getLoginUserPoints($userid);
               if($robotMoney < $smallMoney){  //机器人玩家钱不足以满足房间底注时自动充值(按倍数)
                   $newPoints = 0;
                   $res = PlayCommon::addRobotPoints($userid,$smallMoney,$newPoints);
                   BaseEnum::Logger("机器人加分UID：{$userid} (记录余额：{$robotMoney},门槛分：$smallMoney)  加分后的points={$newPoints} ,操作结果:" . $res, 'user-login');
                   if ($res === TRUE) { $robotMoney = $newPoints;}       //保存在线玩的列表值
                }
                $groupPlayers[] = [
                    "uid" => $userid,
                    'name' => $oneplayer['name'] ?? "",                                                 // 名字
                    "agentId" => isset($oneplayer['agentId']) ? intval($oneplayer['agentId']) : 0,      // 代理用户ID
                    "isNation" => 3,    // 玩家身份:机器人
                    "pstatus" => 0,     // 玩家操作状态
                    "sex" => isset($oneplayer['gender']) ? intval($oneplayer['gender']) : 0,            // 性别
                    "head_id" => isset($oneplayer['head_url']) ? intval($oneplayer['head_url']) : 0,    // 头像
                    "fd" => isset($oneplayer['loginFd']) ? intval($oneplayer['loginFd']) : 0,           // 客户端FD,
                    "points" => $robotMoney,
                    "seatNo" => - 1, // 默认座位为0
                    "mainflag" => 0, // 标识为闲家，默认0
                    "mutdotts" => 0, // 默认倍数；抢庄，下注共用
                    "betmoney" => 0.00
                ];
            }
        }
        $groupPlayers = (!empty($groupPlayers) && sizeof($groupPlayers) > $robNum )  ?  array_slice($groupPlayers, 0,$robNum) : $groupPlayers;
        return $groupPlayers;
    }
    
    /**
     * TODO 加入机器人选玩家操作
     * @param int $gameRId 房间号 
     * @param int $loginFd 玩家FD 
     * @param boolean $userId
     */
    protected function joinIntoRobots($gameRId,$loginFd,$userId=FALSE,$roomInfo=FALSE,$gameOObject=FALSE) {
        //TODO 机器人匹配两秒后处理
        Timer::after(4000, function () use ($gameRId, $loginFd, $userId, $roomInfo,$gameOObject) {
            $gameRes = [
                "gstart" => 0,
                "gameNo" => "",
                "gameInning"=> 1,
                "deskMoney"=>0,
                "isFirst"=>1,
                "roomInfo" => [],
                "players" => []
            ];
            $gameName = isset($roomInfo["gpKey"]) ? $roomInfo["gpKey"] : "";
            $gameText = isset($roomInfo["gfFullName"]) ? $roomInfo["gfFullName"] : @$roomInfo['roomName'];  //房间全名
            $gameId = isset($roomInfo['gameId']) ? intval($roomInfo['gameId']) : 0 ;
            $playNum = isset($roomInfo['playNumber']) ? intval($roomInfo['playNumber']) : 1 ;
            $minPeop = isset($roomInfo["minPlayer"]) ? intval($roomInfo["minPlayer"]) : 0;                  //  最少玩家数据
            $maxPeop = isset($roomInfo["maxPlayer"]) ? intval($roomInfo["maxPlayer"]) : 0;                  //  最高玩家
            $roomLastPots = isset($roomInfo["smallPoints"]) ? floatval($roomInfo["smallPoints"]) : 0;       //  房间的携带分要求；
            $roomEveryPots = isset($roomInfo["everyPoints"]) ? floatval($roomInfo["everyPoints"]) : 0;      //  房间底分
            $maxInMoney = isset($roomInfo['maxInPoints']) ? floatval($roomInfo['maxInPoints']) : 0;         //  最大携带金额；
            $startInMoney = isset($roomInfo['startInPoints']) ? floatval($roomInfo['startInPoints']) : 0;   //  前注分数金额；
            $beforeSmallBet = floatval($roomEveryPots/2);                                                   //  (DZPK)小盲注大小
            
            
            //TODO 对局日志起点分析：记录房间信息（房间名+房间NO + 底注分）
            $startGameLogger = "{$gameText}-[{$gameId}],底分：{$roomEveryPots}";
            
            
            
            //TODO 检查是否有空闲机器人(REDIS 缓存支机器人列表中查询)
            $users = BaseComm::distMemoryPlayer($gameRId,FALSE);
            BaseEnum::Logger("匹配机器人：检测到[{$gameName}-{$gameRId}] 玩家列表=>".json_encode($users),"user-login");
            
            $mySelfUser = isset($users[$userId]) ? $users[$userId] : FALSE;
            
            //默认加一个机器人玩家进来
            $robNum = 1;
            $delUserId = [$userId];
            
            //TODO 检测一下当前玩家是否还在列表中，否则不启动机器人匹配
            if (!empty($users) && !empty($mySelfUser)) {
                unset($users[$userId]);
                $players = [$userId => $mySelfUser];    //组队
                $list_nums = !empty($users) ? sizeof($users) :0 ;
                if (!empty($users) && $list_nums > 0) {
                    $rand_num = ($minPeop >= 2) ?  $minPeop - 1 : 1;
                    if($rand_num > $list_nums){ $rand_num = $list_nums; }
                    $rand_keys =  array_rand($users,$rand_num) ;    //随机取几个玩家KEY
                    if (isset($rand_keys) && is_array($rand_keys)) {
                        foreach ($rand_keys as $rkey){
                            if (isset($rkey) && isset($users[$rkey]) && !empty($users[$rkey])) {
                                array_push($delUserId, $rkey);
                                $players[$rkey] = $users[$rkey];   //随机取到多个玩家 KEY
                            }
                        }
                    }else if(is_int($rand_keys) && intval($rand_keys) > 0 && isset($users[$rand_keys]) && !empty($users[$rand_keys])){
                        array_push($delUserId, $rand_keys);
                        $players[$rand_keys] = $users[$rand_keys];   //随机取到的一个玩家 KEY
                    }
                }
                
                $alreadyNum = sizeof($players);
                //TODO 计算获取取机器人；
                $robNum = ($maxPeop > 0 && $maxPeop >= $minPeop) ? $maxPeop - $alreadyNum : 1;
                BaseEnum::Logger("验证成功：开启机器人功能 ! => 真实玩家：{$alreadyNum}个，需要机器人：{$robNum}个。player =".json_encode($mySelfUser),"user-login");
                
                
                //TODO 挑选机器人玩家(空闲状态)
                $robots  = $this -> getFreeRobotUsers($gameRId,$roomInfo,$robNum);
                BaseEnum::Logger("检测完成：开启机器人功能 => ".json_encode($robots),"user-login");
                if (!$robots  || (!empty($robNum) && sizeof($robots) < $robNum)) {
                    BaseEnum::Logger("匹配失败：查找空闲机器人玩家数量不足，匹配失败。 ","user-login");
                    return FALSE;
                }
                $players = $players + $robots;
                @shuffle($players);
                @shuffle($players);
                $gamePlayers = [];
                $gameMereyFields = [];
                $deskMoney = 0;
                $play_loggers = [];
                $allRecUids  = !empty($players) ? array_column($players, "agentId") : FALSE;  //所有代理UID值 
                //TODO 机器人匹配成功后分配位置
                foreach ($players as $onseat => $tempuser){
                    $uuid = $tempuser['uid'] ?? FALSE;
                    $userFPoints = $tempuser['points'] ?? 0.0;
                    $isNation = isset($tempuser['isNation']) ? intval($tempuser['isNation']): 1;
                    if ($uuid > 0) {
                        $tempuser["fullName"] = $tempuser["name"];
                        if($isNation != 3){
                            $play_loggers[] = "玩家账号 : {$tempuser["name"]},座位号: {$onseat},初始携带分: {$userFPoints}";
                        }
                        $tempuser["name"] = BaseComm::hiddenUserName($tempuser["name"]);     
                        $tempuser['seatNo'] = $onseat;          //分配玩家座位号；
                        $tempuser["maxQzMutle"] = 3;            //牛牛3倍
                        //TODO 抢庄倍数： 抢庄玩家本局能承受的最大赔付金额是低注的多少倍数。
                        if ($gameId == 102) {
                            $gameMereyFields["isFirst"] = 1;
                            $countMaxMut = (isset($tempuser["points"]) && floatval($tempuser["points"]) > $roomEveryPots) ? intval($tempuser["points"]/$roomEveryPots) : 1;
                            $tempuser["maxQzMutle"] = (isset($countMaxMut) && $countMaxMut > 200) ? 200 : $countMaxMut; //最小倍数
                        }else if($gameId == 112){
                            
                            $tempuser["maxQzMutle"] = 4;                           //牌九抢庄倍数最大4倍
                        }else if ($gameId == 116){
                            //德州扑克的真实玩家携带金额分数（不是玩家余额,机器人带满）
                            if($isNation === 3){
                                $tempuser['points'] = $maxInMoney;
                            }
                            
                            $beforeMoney = $startInMoney ; //前注金额
                            if($onseat === 0){
                                $tempuser["mainflag"] =  1;              //第一位为庄家
                            }else if ($onseat === 1) {
                                $beforeMoney += $beforeSmallBet;         // 第二个玩家下小盲注
                            }else if ($onseat === 2) {
                                $beforeMoney += $roomEveryPots;          // 第三个玩家下小盲注
                            }
                            $tempuser['play_lun'] = 0;                          // 轮
                            $tempuser['betmoney'] = $beforeMoney;               // 大/小盲注
                            $tempuser['blind_money'] = $beforeMoney;            // 大/小盲注
                            $tempuser['total_money'] = $beforeMoney;            // 大/小盲注
                            $tempuser['play_lunmoney'] = $beforeMoney;          // 当前这一轮的所有玩家下注金额都要一样
                            $deskMoney = bcadd($deskMoney, $beforeMoney , 2);   //桌面上的分数
                            $startGameLogger = "{$gameText}-[{$gameId}],大小盲注分：{$roomEveryPots}/{$beforeSmallBet} ";
                        }
                        $gamePlayers[$onseat] = $tempuser;
                        
                        //TODO 内存数据扩展字段
                        $gameMereyFields["lastSiteNo"] = 2 ;                          //最后下注的位置索引刚开始为第四个人； 轮回操作(0-1-2-3 - 0-1-2-3....)
                        $gameMereyFields["deskMoney"] = floatval($deskMoney);         //桌面保存的金额
                    }
                }
                BaseEnum::Logger("机器人匹配完成：机器人={$robNum}个，分配座位：AllPlayers =".json_encode($gamePlayers),"user-login");
                
                //TODO 游戏重新开局
                $allFds = !empty($gamePlayers) ? array_column($gamePlayers, "fd","seatNo") :FALSE;
                $roomInfo["users_num"] = sizeof($gamePlayers);
                $roomInfo["users"] = $gamePlayers; // 游戏数据
                $roomInfo["agentsIds"] = !empty($allRecUids) ? array_unique($allRecUids) : FALSE ; // 游戏数据
                BaseEnum::Logger("游戏开局成功：FjFdLists =".json_encode($allFds),"user-login");
                
                //TODO 游戏开始=== 获取房间编号
                $gameNo = GameCommon::openGameSuccess($gameId, $gameRId, $gamePlayers,$playNum,$roomInfo["users_num"],$gameMereyFields);
                if(!$gameNo){
                    BaseEnum::Logger("创建游戏检测：(joinGameRidUsers)-开启失败..>>>" . json_encode($gamePlayers), 'user-login');
                    return FALSE;
                }
                
                $gameLogs = array_merge([$startGameLogger],$play_loggers);
                /************************************需要开局插入DB的游戏**********************************/
                $robotDbEx = GameCommon::createRoomsPlayinfo($gameRId, $gameNo, $roomInfo, $userId);             // 房间落地写入DB并开始发牌
                //TODO 写入成功，游戏开始
                if ($robotDbEx === true) {
                    
                    BaseComm::gameLogger($gameNo,$gameLogs,FALSE);       //对局开始日志
                    BaseEnum::Logger("机器人匹配成功写DB成功：WsBase-(joinIntoRobots)，开始游戏[{$gameNo}]---->>>".$gameRId, 'user-login');
                    $gameRes["gstart"] = 1;                                     // 有开局，(自动匹配)直接进入；要写DB操作；
                    $gameRes["gameNo"] = $gameNo;
                    $gameRes["deskMoney"] = floatval($deskMoney);               // 桌面上的余额
                    $gameRes["roomInfo"] = array("gameId"=>$gameId,"everyPoints"=>$roomEveryPots,"smallPoints"=>$roomLastPots,"maxInMoney"=> $maxInMoney,"curInning"=> 1,"total"=>$playNum); //默认为第一局
                    $gameRes["players"] = $gamePlayers;                         // 有开局，(自动匹配)直接进入；要写DB操作；
                    BaseEnum::Logger("房间内数据：Finish=> ". json_encode($gameRes),"user-login");
                    
                    //TODO 机器人匹配成功后，列队数据清空；游戏继续进行
                    $NewLists = BaseComm::distMemoryPlayer($gameRId,FALSE);
                    foreach ($delUserId as $oneuuid){
                        if (!empty($NewLists) && array_key_exists($oneuuid, $NewLists)) {
                            unset($NewLists[$oneuuid]);
                        }
                    }
                    $NewLists = !empty($NewLists) ? $NewLists : FALSE;
                    
                    //TODO 组织所有的玩家数据进入游戏时判断一下是否玩家已经取消游戏
                    $firstUserHand =  PlayHelp::getInstance() -> getPlayerOpenHands($userId);                       // 玩家取消标识
                    if (!empty($firstUserHand) && $firstUserHand == 'PLAY_CANCEL') {                                // 已取消不再继续游戏
                        $loggmsg = "因玩家手动取消,游戏结束。";
                        BaseEnum::Logger("检测到游戏发起匹配时：{$loggmsg} [{$gameName},{$gameRId},{$gameNo}]---->游戏结束； PlayUids = " . json_encode($delUserId), 'user-login');
                        PlayHelp::getInstance()->setPlayerOpenHands($userId,FALSE);         //TODO 玩家取消标识
                        BaseComm::distLastGameNoListRedis([$userId],TRUE, FALSE);           //TODO 清空玩家最近的房间号
                        BaseComm::gameLogger($gameNo,$loggmsg,['finish'=>TRUE]);            //TODO 对局开始日志 
                        return FALSE;
                    }
                    BaseComm::distMemoryPlayer($gameRId,TRUE,$NewLists);
                    //游戏开始(asycStartGame)
                    if (isset($gameOObject) && !empty($gameOObject) && isset($gameOObject -> baseGameName) && $gameOObject -> baseGameName == $gameName && !empty($allFds) && !empty($gameRes)) {
                        //TODO 推送每个玩家
                        AuthCommon::pushFrontWeb($allFds, json_encode([ 'm' => BaseEnum::XYM_0X16, "data" => $gameRes ])); // 推送相同内容
                        BaseEnum::Logger("机器人互动：Games-(joinIntoRobots)，[{$gameName}]---->" . json_encode($gameOObject), 'user-login');
                        
                        $gameOObject -> setGameStatus("START");                     //TODO 启动开始
                        BaseComm::gameLogger($gameNo,"游戏开始   , 抢庄");            //TODO 对局开始日志
                        $gameOObject -> asycStartGame($gameNo, $gameRId, $roomInfo);
                    }else{
                        BaseEnum::Logger("机器人匹配失败：Games-(joinIntoRobots)-getClassObject，[{$gameName}]----失败!!!!" . json_encode([$userId,$gameRId]), 'user-login');
                    }
                }else{
                    BaseEnum::Logger("机器人写库失败：Games-(joinIntoRobots)，[{$gameName}]----失败!!!!", 'user-login');
                }
                
                /************************************需要开局插入DB的游戏**********************************/
            }
        });
    }
    
    
}